package com.dinnovate.dxf.analysis;

import com.dinnovate.dxf.enums.FileStructEnum;
import com.dinnovate.dxf.enums.PointEnum;
import org.apache.commons.collections4.CollectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.dinnovate.dxf.service.dxfDataService.readAllLine;

public class DxfAnalysis {
    /**
     * 返回几何图像解析数据
     *
     * @param reader BufferedReader
     * @return 解析的数据
     * @throws IOException IO异常
     */
    public static List<List<String>> getGeometricListMap(BufferedReader reader) throws IOException {

        List<List<String>> pointNumList = new ArrayList<>();

        //点数据_第一次获取为标头
        List<String> Startpoint = getHeaderStrings();
        pointNumList.add(Startpoint);

        //读取dxf所有的数据
        List<String> lineList = readAllLine(reader);
//        存放实体数据
        List<String> lineLists = new ArrayList<>();
//        截取总数据中的实体数据进行处理
        int lineStart = 0;
        for (String line : lineList) {
            if (!line.equals(FileStructEnum.ENTITIES_START.getCode()) && lineStart == 0) {
                continue;
            }
            lineStart = 1;
            lineLists.add(line);
        }
        parseFile(lineLists, pointNumList);
        return pointNumList;
    }

    /**
     * 解析dxf文件结构
     *
     * @param lineList 总数据
     * @param map      接收解析的数据map
     */
    private static void parseFile(List<String> lineList, List<List<String>> map) {
//        总数据不为空
        if (CollectionUtils.isEmpty(lineList)) {
            return;
        }
        int i = 0;
        String str = lineList.get(i);
        //未到文件结束标志则一直进行
        while (!FileStructEnum.FILE_END.getCode().equals(str)) {
            str = lineList.get(++i);
//            解析实体数据中的图元数据
            if (str.equals(PointEnum.INSERT_NAME.getCode())) {
                i = parseEntities(i, lineList, map);
                str = lineList.get(i);
            }
        }
        // 解析函数结束
    }

    /**
     * 解析实体
     *
     * @param i        实体开始读取的行数
     * @param lineList 总数据
     * @param map      接收解析的数据map
     */
    private static int parseEntities(int i, List<String> lineList, List<List<String>> map) {
        String str;
        do {
            str = lineList.get(++i);
//            点图层数据
            if (str.equals(PointEnum.LAYER_NAME.getCode())) {
                str = lineList.get(++i);

                if (!str.equals(PointEnum.POINT_NAME.getCode())) {
                    break;
                } else {
                    //PS_WSG_POINT
                    i = getPoint(i, lineList, map);
                    str = lineList.get(i);
                }
            }

            //实体模块结束
        } while (!str.equals(FileStructEnum.END_SEC.getCode()));
        // 实体段结束
        return  i;
    }

    /**
     * 解析点
     *
     * @param i        点开始读取的行数
     * @param lineList 总数据
     * @param map      接收解析的数据map
     * @return 返回点读完的最后行数
     */
    private static int getPoint(int i, List<String> lineList, List<List<String>> map) {
        String str = lineList.get(i);

        List<String> point = getHeaderStrings();

        point.set(0, str);//PS_WSG_POINT图层名称给值

        do {
            str = lineList.get(++i);
            //--------------------------------
//            System.out.println("解析点：" + i);
//            X坐标
            if (str.equals(PointEnum.COORDINATE_X.getCode())) {
                str = lineList.get(++i);
                point.set(1, str.trim());
            }
//            Y坐标
            if (str.equals(PointEnum.COORDINATE_Y.getCode())) {
                str = lineList.get(++i);
                point.set(2, str.trim());
            }
//            Z坐标
            if (str.equals(PointEnum.COORDINATE_Z.getCode())) {
                str = lineList.get(++i);
                point.set(3, str.trim());
            }
//            高程
            if (str.contains(PointEnum.COORDINATE_ELEVATION.getCode())) {
//                数据处理
                String elevation = str.substring(str.indexOf(":") + 1);
                point.set(4, elevation.trim());
            }
//            物探点号
            if (str.contains(PointEnum.COORDINATE_POINT_NUMBER.getCode())) {
//                物探点号数据处理
                String newPointNum = str.substring(str.indexOf("/") + 1);
                String pointName = newPointNum.substring(0, newPointNum.indexOf("/"));
                point.set(5, pointName.trim());
            }
//            要素代码
            if (str.contains(PointEnum.COORDINATE_ELEMENT_CODE.getCode())) {
//                要素代码数据处理
                String elementCode = str.substring(str.indexOf(":") + 1);
                point.set(6, elementCode.trim());
            }
//            System.out.println(str);
        } while (!str.equals(FileStructEnum.END_SEC.getCode()) && !str.equals(PointEnum.INSERT_NAME.getCode()) && !FileStructEnum.FILE_END.getCode().equals(str));
//        将该点处理后值加入到列表中
        map.add(point);

        return i;
    }

    private static List<String> getHeaderStrings() {
        List<String> Startpoint = new ArrayList<>();
        Startpoint.add(PointEnum.LAYER_NAME.getFieldName());//图层名称
        Startpoint.add(PointEnum.COORDINATE_X.getFieldName());//X坐标
        Startpoint.add(PointEnum.COORDINATE_Y.getFieldName());//Y坐标
        Startpoint.add(PointEnum.COORDINATE_Z.getFieldName());//Z坐标
        Startpoint.add(PointEnum.COORDINATE_ELEVATION.getFieldName());//高程
        Startpoint.add(PointEnum.COORDINATE_POINT_NUMBER.getFieldName());//物探点号
        Startpoint.add(PointEnum.COORDINATE_ELEMENT_CODE.getFieldName());//要素代码
        return Startpoint;
    }
}
